<?php
/**
 * Парсер сайтов. 
 * @version 0.1Beta
 * @author Oleg G.
 * 
 *
 */
class Parser {
	
	protected $hostname; // URL сайта
	protected $filep; // Указатель на сайт. 
	
	protected  $div_begin; // Начало искомого блока div
	protected  $div_id; // Идентификатор искомого блока div
	protected  $div_end; // Конец искомого блока div
	protected  $div_result; // Найденый блок div 
	
	protected  $fp_str; // Строка, куда считывается сайт
	
	
	/**
	 * 
	 * Конструктор
	 * @param $hostname
	 */
	function __construct($hn){
		$this->hostname = $hn;	
	}
	
	function __destruct(){
		if(isset($this->filep)) fclose($this->filep);
	}
	/**
	 * Устанавливает hostname с которого производится чтение.
	 * Set $hostname ...
	 * @param string $hostname
	 */
	protected function SetHostname($host) {
		
		$this->hostname = $host;
		return ;
	}

	/**
	 * Подключение к сайту через fsockopen
	 * 
	 *@return $fp
	 */
	protected function Get() {
		$fp = fsockopen($this->hostname,80);

		$str = "GET / HTTP/1.1\r\n";
		fputs($fp, $str);

		$str = "Host: " . $this->hostname . "\r\n";
		fputs($fp, $str);

		$str = "Connection: close\r\n";
		fputs($fp, $str);

		$str = "\r\n";
		fputs($fp, $str);
		
		$this->filep = $fp;
		return $fp;
	}


	/**
	 * Открытие файла на сайте.
	 */
	protected function SiteOpen() {
		$fp = fopen($this->hostname, "r");
		$this->filep = $fp;
		return $this->filep;
	}
	
	/**
	 * Открытие файла и считывание его в строку.
	 */
	protected function SiteGetContent(){
		$this->fp_str = file_get_contents($this->hostname);
		
	}
	
	/**
	 * Парсинг блока поиска с вхождением во внутренние блоки.
	 * 	
	 * Принимает:
	 * @param integer $ps_b // Первое вхождение искомого блока в строку
	 * @param integer $ps_depth // Глубина вхождения. Нужно для рекурсии
	 * @return array $ps_return[] //Позиция в строке закрывающего тега искомого блока
	 */
	protected function ParsSearch($ps_b = null,$ps_depth = 0){
		$ps_in = null;
		$ps_out = null;
		$ps_flag = null;
		$ps_b++;
		
		$ps_out = strpos($this->fp_str, $this->div_end, $ps_b);
		$ps_in = strpos($this->fp_str, $this->div_begin, $ps_b);
		
		if($ps_in == FALSE){
			$ps_flag = (-1);
			$ps_b = $ps_out;
			$ps_depth--;
			if($ps_out == FALSE) return (-1);
		}
		else{
		if($ps_out == FALSE) return (-1);

			if($ps_out > $ps_in){
				$ps_flag = 1;
				$ps_b = $ps_in;
				$ps_depth++;	
			}
			if($ps_out < $ps_in){
				$ps_flag = (-1);
				$ps_b = $ps_out;
				$ps_depth--;
			}
		}
		//Вход в рекурс
		if($ps_flag ==1){
			while ($ps_depth >= 0){
				$ps_res = $this->ParsSearch($ps_b,$ps_depth);
				if ($ps_res == -1) break;
				$ps_b = $ps_res['ps_b'];
				$ps_depth = $ps_res['ps_depth'];
			} 
		}
		$ps_return['ps_b'] = $ps_b;
		$ps_return['ps_depth'] = $ps_depth;
		return $ps_return;
	}
	
	/**
	 * Поиск установленного блока DIV.
	 * 
	 * @param string $begin_div // Например: <div>
	 * @param string $id_div // Например: <div class="myclass">
	 * @param string $end_div // Например: </div>
	 * @return string $res Результат. Нужный DIV, включая теги
	 */
	function GetDiv($begin_div,$id_div,$end_div){
		
		$this->div_begin = $begin_div;
		$this->div_id = $id_div;
		$this->div_end = $end_div;
		
		$this->SiteGetContent();
		
		$pars = null;
		$pars_begin = null;
		$pars_end = null;
		
		$pars = strpos($this->fp_str, $this->div_id);
		$pars_begin = $pars;
		
		$ps_res = $this->ParsSearch($pars_begin);
		$pars_end = $ps_res['ps_b'];
		
		$res_len = $pars_end - $pars_begin;
		$res_len += strlen($this->div_end);
		$this->div_result = substr($this->fp_str, $pars, $res_len);
		
		return $this->div_result;	
	}


}
